package com.alogic.ac.impl;

import com.alogic.ac.AbstractACMAccessController;
import com.alogic.ac.AccessControlModel;
import com.alogic.matcher.CommonMatcher;
import com.alogic.matcher.MatcherFactory;
import com.anysoft.util.BaseException;
import com.anysoft.util.Properties;
import com.anysoft.util.PropertiesConstants;
import com.anysoft.util.XmlElementProperties;
import com.logicbus.backend.Context;
import com.logicbus.models.catalog.Path;
import com.logicbus.models.servant.ServiceDescription;
import org.w3c.dom.Element;

import java.util.ArrayList;
import java.util.List;

/**
 * IP限制
 *
 * @since 1.6.14.6 [20210415 duanyy] <br>
 */
public class IpLimit extends AbstractACMAccessController {
    /**
     * 所有登录用户采用同一个ACM
     */
    protected AccessControlModel acm = null;

    /**
     * ip匹配器
     */
    protected List<CommonMatcher> whitelist = new ArrayList<CommonMatcher>();

    @Override
    public void configure(Element e, Properties props) {
        XmlElementProperties p = new XmlElementProperties(e,props);
        configure(p);
        acm = new AccessControlModel.Default();
        acm.configure(e, props);
    }

    @Override
    public void configure(Properties p){
        super.configure(p);
        String[] list = PropertiesConstants.getString(p,"whitelist","(wildcard)*")
                .split(PropertiesConstants.getString(p,"delimiter",";"));
        for (String item:list){
            try {
                CommonMatcher matcher = MatcherFactory.getMatcher(item, p);
                whitelist.add(matcher);
            }catch (Exception ex){
                LOG.error("Can not create matcher:" + item);
            }
        }
    }

    @Override
    public void reload(String id) {
        // nothing to reload
    }

    @Override
    public String createSessionId(Path serviceId, ServiceDescription servant, Context ctx) {
        String clientIp = this.getClientIp(ctx);
        boolean allow = false;
        for (CommonMatcher matcher:whitelist){
            if (matcher.isMatch(clientIp)){
                allow = true;
                break;
            }
        }
        if (allow){
            return clientIp;
        }else{
            LOG.info(String.format("%s is not allow to access now",clientIp));
            throw new BaseException("core.e1019",String.format("%s is not allow to access now",clientIp));
        }
    }

    @Override
    protected AccessControlModel getACM(String sessionId, Path serviceId, ServiceDescription servant, Context ctx) {
        return acm;
    }
}